home *** CD-ROM | disk | FTP | other *** search
- # -*- coding: utf-8 -*-
- #
- # (c) Copyright 2003-2008 Hewlett-Packard Development Company, L.P.
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- #
- # Author: Don Welch
- #
-
- # Std Lib
- import socket
- import re
- import gzip
- import os.path
- import time
- import urllib # TODO: Replace with urllib2 (urllib is deprecated in Python 3.0)
- import StringIO
- import httplib
- import struct
-
- # Local
- from g import *
- from codes import *
- import utils
- import status
- import pml
- from prnt import pcl, ldl, cups
- import models, mdns, slp
- from strings import StringTable
-
-
- try:
- import hpmudext
- except ImportError:
- if not os.getenv("HPLIP_BUILD"):
- log.error("HPMUDEXT could not be loaded. Please check HPLIP installation.")
- sys.exit(1)
-
-
- dbus_avail = False
- dbus_disabled = False
- try:
- import dbus
- dbus_avail = True
- except ImportError:
- log.warn("python-dbus not installed.")
-
-
- DEFAULT_PROBE_BUS = ['usb', 'par', 'cups']
- VALID_BUSES = ('par', 'net', 'cups', 'usb') #, 'bt', 'fw')
- VALID_BUSES_WO_CUPS = ('par', 'net', 'usb')
- DEFAULT_FILTER = None
- VALID_FILTERS = ('print', 'scan', 'fax', 'pcard', 'copy')
-
- pat_deviceuri = re.compile(r"""(.*):/(.*?)/(\S*?)\?(?:serial=(\S*)|device=(\S*)|ip=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[^&]*))(?:&port=(\d))?""", re.IGNORECASE)
- http_pat_url = re.compile(r"""/(.*?)/(\S*?)\?(?:serial=(\S*)|device=(\S*))&loc=(\S*)""", re.IGNORECASE)
- direct_pat = re.compile(r'direct (.*?) "(.*?)" "(.*?)" "(.*?)"', re.IGNORECASE)
-
- # Pattern to check for ; at end of CTR fields
- # Note: If ; not present, CTR value is invalid
- pat_dynamic_ctr = re.compile(r"""CTR:\d*\s.*;""", re.IGNORECASE)
-
- MAX_BUFFER = 8192
-
- # Cache for model data
- model_dat = models.ModelData()
-
- ip_pat = re.compile(r"""\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b""", re.IGNORECASE)
-
- dev_pat = re.compile(r"""/dev/.+""", re.IGNORECASE)
- usb_pat = re.compile(r"""(\d+):(\d+)""", re.IGNORECASE)
-
-
- class Event(object):
- def __init__(self, device_uri, printer_name, event_code, username, job_id, title, timedate=0):
- self.device_uri = str(device_uri).replace('\x00', '')
- self.printer_name = str(printer_name).replace('\x00', '')
- self.event_code = int(event_code)
- self.username = str(username).replace('\x00', '')
- self.job_id = int(job_id)
- self.title = str(title).replace('\x00', '')
-
- if timedate:
- self.timedate = float(timedate)
- else:
- self.timedate = time.time()
-
- self.fmt = "64s64sI32sI64sf"
-
- def debug(self):
- log.debug(" device_uri=%s" % self.device_uri)
- log.debug(" printer_name=%s" % self.printer_name)
- log.debug(" event_code=%d" % self.event_code)
- log.debug(" username=%s" % self.username)
- log.debug(" job_id=%d" % self.job_id)
- log.debug(" title=%s" % self.title)
- log.debug(" timedate=%s" % self.timedate)
-
- def pack(self): # pack up for transport in pipe between hpssd and systemtray_ui and between toolbox and toolbox dbus receiver
- return struct.pack(self.fmt, self.device_uri[:64], self.printer_name[:64],
- self.event_code, self.username[:32], self.job_id, self.title[:64], self.timedate)
-
- def __str__(self):
- return "<Event('%s', '%s', %d, '%s', %d, '%s', %f)>" % self.as_tuple()
-
-
- def as_tuple(self):
- return (self.device_uri, self.printer_name, self.event_code,
- self.username, self.job_id, self.title, self.timedate)
-
-
-
- def init_dbus():
- global dbus_avail
- service = None
-
- if dbus_avail and not dbus_disabled:
- if os.getuid() == 0:
- log.debug("Not starting dbus: running as root.")
- dbus_avail = False
- return dbus_avail, None
-
- try:
- session_bus = dbus.SessionBus()
- except dbus.exceptions.DBusException, e:
- if os.getuid() != 0:
- log.error("Unable to connect to dbus session bus.")
- else:
- log.debug("Unable to connect to dbus session bus (running as root?)")
-
- dbus_avail = False
- return dbus_avail, None
-
- try:
- log.debug("Connecting to com.hplip.StatusService (try #1)...")
- service = session_bus.get_object('com.hplip.StatusService', "/com/hplip/StatusService")
- dbus_avail = True
- except dbus.exceptions.DBusException, e:
- try:
- os.waitpid(-1, os.WNOHANG)
- except OSError:
- pass
-
- path = utils.which('hp-systray')
- if path:
- path = os.path.join(path, 'hp-systray')
- else:
- path = os.path.join(prop.home_dir, 'systray.py')
- if not os.path.exists(path):
- log.warn("Unable to start hp-systray")
- return False, None
-
- log.debug("Running hp-systray: %s --qt4 --force-startup" % path)
- os.spawnlp(os.P_NOWAIT, path, 'hp-systray', '--qt4',
- '--force-startup')
-
- log.debug("Waiting for hp-systray to start...")
- time.sleep(1)
-
- t = 2
- while True:
- try:
- log.debug("Connecting to com.hplip.StatusService (try #%d)..." % t)
- service = session_bus.get_object('com.hplip.StatusService', "/com/hplip/StatusService")
-
- except dbus.exceptions.DBusException, e:
- log.debug("Unable to connect to dbus. Is hp-systray running?")
- t += 1
-
- if t > 5:
- return False, None
-
- time.sleep(1)
-
- else:
- log.debug("Connected.")
- dbus_avail = True
- break
-
- return dbus_avail, service
-
-
- def makeURI(param, port=1):
- cups_uri, sane_uri, fax_uri = '', '', ''
- found = False
-
- # see if the param represents a hostname
- try:
- param = socket.gethostbyname(param)
- except socket.gaierror:
- log.debug("Gethostbyname() failed. Trying other patterns...")
-
- if dev_pat.search(param) is not None: # parallel
- log.debug("Trying parallel with %s" % param)
-
- result_code, uri = hpmudext.make_par_uri(param)
-
- if result_code == hpmudext.HPMUD_R_OK and uri:
- log.debug("Found: %s" % uri)
- found = True
- cups_uri = uri
- else:
- log.debug("Not found.")
-
- elif usb_pat.search(param) is not None: # USB
- match_obj = usb_pat.search(param)
- usb_bus_id = match_obj.group(1)
- usb_dev_id = match_obj.group(2)
-
- log.debug("Trying USB with bus=%s dev=%s..." % (usb_bus_id, usb_dev_id))
- result_code, uri = hpmudext.make_usb_uri(usb_bus_id, usb_dev_id)
-
- if result_code == ERROR_SUCCESS and uri:
- log.debug("Found: %s" % uri)
- found = True
- cups_uri = uri
- else:
- log.debug("Not found.")
-
- elif ip_pat.search(param) is not None: # IPv4 dotted quad
- log.debug("Trying IP address %s" % param)
-
- result_code, uri = hpmudext.make_net_uri(param, port)
-
- if result_code == hpmudext.HPMUD_R_OK and uri:
- log.debug("Found: %s" % uri)
- found = True
- cups_uri = uri
- else:
- log.debug("Not found.")
-
- else: # serial
- log.debug("Trying serial number %s" % param)
- devices = probeDevices(bus=['usb', 'par'])
-
- for d in devices:
- log.debug(d)
-
- # usb has serial in URI...
- try:
- back_end, is_hp, bus, model, serial, dev_file, host, port = \
- parseDeviceURI(d)
- except Error:
- continue
-
- if bus == 'par': # ...parallel does not. Must get Device ID to obtain it...
- mq = queryModelByURI(d)
-
- result_code, device_id = \
- hpmudext.device_open(d, mq.get('io-mode', hpmudext.HPMUD_UNI_MODE))
-
- if result_code == hpmudext.HPMUD_R_OK:
- result_code, data = hpmudext.get_device_id(device_id)
- serial = parseDeviceID(data).get('SN', '')
- hpmudext.close_device(device_id)
-
- if serial.lower() == param.lower():
- #log.debug("Match")
- log.debug("Found: %s" % d)
- found = True
- cups_uri = d
- break
- else:
- log.debug("Not found.")
-
- if found:
- try:
- mq = queryModelByURI(cups_uri)
- except Error, e:
- log.error("Error: %s" % e.msg)
- cups_uri, sane_uri, fax_uri = '', '', ''
- else:
- if mq.get('scan-type', 0):
- sane_uri = cups_uri.replace("hp:", "hpaio:")
-
- if mq.get('fax-type', 0):
- fax_uri = cups_uri.replace("hp:", "hpfax:")
-
- else:
- scan_uri, fax_uri = '', ''
-
- if cups_uri:
- user_cfg.last_used.device_uri = cups_uri
-
- return cups_uri, sane_uri, fax_uri
-
-
- def queryModelByModel(model):
- model = models.normalizeModelName(model).lower()
- return model_dat[model]
-
- def queryModelByURI(device_uri):
- try:
- back_end, is_hp, bus, model, \
- serial, dev_file, host, port = \
- parseDeviceURI(device_uri)
- except Error:
- raise Error(ERROR_INVALID_DEVICE_URI)
- else:
- return queryModelByModel(model)
-
-
- def __checkFilter(filter, mq):
- for f, p in filter.items():
- if f is not None:
- op, val = p
- if not op(mq[f], val):
- return False
-
- return True
-
-
- def enter_range(question, min_value, max_value, default_value=None):
- while True:
- user_input = raw_input(log.bold(question)).lower().strip()
-
- if not user_input:
- if default_value is not None:
- return True, default_value
-
- if user_input == 'q':
- return False, default_value
-
- try:
- value_int = int(user_input)
- except ValueError:
- log.error('Please enter a number between %d and %d, or "q" to quit.' %
- (min_value, max_value))
- continue
-
- if value_int < min_value or value_int > max_value:
- log.error('Please enter a number between %d and %d, or "q" to quit.' %
- (min_value, max_value))
- continue
-
- return True, value_int
-
-
-
- def getInteractiveDeviceURI(bus=DEFAULT_PROBE_BUS, filter=DEFAULT_FILTER, back_end_filter=('hp',)):
- probed_devices = probeDevices(bus, filter=filter)
- cups_printers = cups.getPrinters()
- log.debug(probed_devices)
- log.debug(cups_printers)
- max_deviceid_size, x, devices = 0, 0, {}
-
- for d in probed_devices:
- printers = []
-
- back_end, is_hp, b, model, serial, dev_file, host, port = \
- parseDeviceURI(d)
-
- if back_end in back_end_filter:
- for p in cups_printers:
- if p.device_uri == d:
- printers.append(p.name)
-
- devices[x] = (d, printers)
- x += 1
- max_deviceid_size = max(len(d), max_deviceid_size)
-
- if x == 0:
- log.error("No devices found.")
- raise Error(ERROR_NO_PROBED_DEVICES_FOUND)
-
- elif x == 1:
- log.info(log.bold("Using device: %s" % devices[0][0]))
- user_cfg.last_used.device_uri = devices[0][0]
- return devices[0][0]
-
- else:
- last_used_device_uri = user_cfg.last_used.device_uri
- last_used_index = None
-
- rows, cols = utils.ttysize()
- if cols > 100: cols = 100
-
- log.info(log.bold("\nChoose device from probed devices connected on bus(es): %s:\n" % ','.join(bus)))
- formatter = utils.TextFormatter(
- (
- {'width': 4},
- {'width': max_deviceid_size, 'margin': 2},
- {'width': cols-max_deviceid_size-8, 'margin': 2},
- )
- )
- log.info(formatter.compose(("Num.", "Device-URI", "CUPS printer(s)")))
- log.info(formatter.compose(('-'*4, '-'*(max_deviceid_size), '-'*(cols-max_deviceid_size-10))))
-
- for y in range(x):
- log.info(formatter.compose((str(y), devices[y][0], ', '.join(devices[y][1]))))
-
- if last_used_device_uri == devices[y][0]:
- last_used_index = y
-
- if last_used_index is not None:
- ok, i = enter_range("\nEnter number 0...%d for device (q=quit, enter=last used device: %s) ?" %
- ((x-1), last_used_device_uri), 0, (x-1), -1)
-
- else:
- ok, i = enter_range("\nEnter number 0...%d for device (q=quit) ?" %
- (x-1), 0, (x-1), -1)
-
- if not ok:
- sys.exit(0)
-
- if last_used_index is not None and i == -1:
- i = last_used_index
-
- user_cfg.last_used.device_uri = devices[i][0]
- return devices[i][0]
-
-
- def probeDevices(bus=DEFAULT_PROBE_BUS, timeout=10,
- ttl=4, filter=DEFAULT_FILTER, search='', net_search='slp',
- back_end_filter=('hp',)):
-
- num_devices, ret_devices = 0, {}
-
- if search:
- try:
- search_pat = re.compile(search, re.IGNORECASE)
- except:
- log.error("Invalid search pattern. Search uses standard regular expressions. For more info, see: http://www.amk.ca/python/howto/regex/")
- search = ''
-
- for b in bus:
- log.debug("Probing bus: %s" % b)
- if b not in VALID_BUSES:
- log.error("Invalid bus: %s" % b)
- continue
-
- if b == 'net':
- if net_search == 'slp':
- try:
- detected_devices = slp.detectNetworkDevices(ttl, timeout)
- except Error, socket.error:
- log.error("An error occured during network probe.")
- raise ERROR_INTERNAL
- else:
- try:
- detected_devices = mdns.detectNetworkDevices(ttl, timeout)
- except Error, socket.error:
- log.error("An error occured during network probe.")
- raise ERROR_INTERNAL
-
- for ip in detected_devices:
- update_spinner()
- hn = detected_devices[ip].get('hn', '?UNKNOWN?')
- num_devices_on_jd = detected_devices[ip].get('num_devices', 0)
- num_ports_on_jd = detected_devices[ip].get('num_ports', 1)
-
- if num_devices_on_jd > 0:
- for port in range(num_ports_on_jd):
- dev = detected_devices[ip].get('device%d' % (port+1), '0')
-
- if dev is not None and dev != '0':
- device_id = parseDeviceID(dev)
- model = models.normalizeModelName(device_id.get('MDL', '?UNKNOWN?'))
-
- if num_ports_on_jd == 1:
- device_uri = 'hp:/net/%s?ip=%s' % (model, ip)
- else:
- device_uri = 'hp:/net/%s?ip=%s&port=%d' % (model, ip, (port+1))
-
- include = True
- mq = queryModelByModel(model)
-
- if not mq:
- log.debug("Not found.")
- include = False
-
- elif int(mq.get('support-type', SUPPORT_TYPE_NONE)) == SUPPORT_TYPE_NONE:
- log.debug("Not supported.")
- include = False
-
- elif filter not in (None, 'print', 'print-type'):
- include = __checkFilter(filter, mq)
-
- if include:
- ret_devices[device_uri] = (model, model, hn)
-
- elif b in ('usb', 'par'):
- if b == 'par':
- bn = hpmudext.HPMUD_BUS_PARALLEL
- else:
- bn = hpmudext.HPMUD_BUS_USB
-
- result_code, data = hpmudext.probe_devices(bn)
-
- if result_code == hpmudext.HPMUD_R_OK:
- for x in data.splitlines():
- m = direct_pat.match(x)
-
- uri = m.group(1) or ''
- mdl = m.group(2) or ''
- desc = m.group(3) or ''
- devid = m.group(4) or ''
-
- log.debug(uri)
-
- try:
- back_end, is_hp, bb, model, serial, dev_file, host, port = \
- parseDeviceURI(uri)
- except Error:
- continue
-
- include = True
-
- if mdl and uri and is_hp:
- mq = queryModelByModel(model)
-
- if not mq:
- log.debug("Not found.")
- include = False
-
- elif int(mq.get('support-type', SUPPORT_TYPE_NONE)) == SUPPORT_TYPE_NONE:
- log.debug("Not supported.")
- include = False
-
- elif filter not in (None, 'print', 'print-type'):
- include = __checkFilter(filter, mq)
-
- if include:
- ret_devices[uri] = (mdl, desc, devid) # model w/ _'s, mdl w/o
-
- elif b == 'cups':
- cups_printers = cups.getPrinters()
- x = len(cups_printers)
-
- for p in cups_printers:
- device_uri = p.device_uri
- log.debug("%s: %s" % (device_uri, p.name))
-
- if device_uri != '':
- try:
- back_end, is_hp, bs, model, serial, dev_file, host, port = \
- parseDeviceURI(device_uri)
- except Error:
- log.debug("Unrecognized URI: %s" % device_uri)
- continue
-
- if not is_hp:
- continue
-
- include = True
- mq = queryModelByModel(model)
-
- if not mq:
- include = False
- log.debug("Not found.")
-
- elif int(mq.get('support-type', SUPPORT_TYPE_NONE)) == SUPPORT_TYPE_NONE:
- log.debug("Not supported.")
- include = False
-
- elif filter not in (None, 'print', 'print-type'):
- include = __checkFilter(filter, mq)
-
- if include:
- ret_devices[device_uri] = (model, model, '')
-
- probed_devices = {}
- for uri in ret_devices:
- num_devices += 1
- mdl, model, devid_or_hn = ret_devices[uri]
-
- include = True
- if search:
- match_obj = search_pat.search("%s %s %s %s" % (mdl, model, devid_or_hn, uri))
-
- if match_obj is None:
- log.debug("%s %s %s %s: Does not match search '%s'." % (mdl, model, devid_or_hn, uri, search))
- include = False
-
- if include:
- probed_devices[uri] = ret_devices[uri]
-
- cleanup_spinner()
- return probed_devices
-
-
- def getSupportedCUPSDevices(back_end_filter=['hp']):
- devices = {}
- printers = cups.getPrinters()
-
- for p in printers:
- try:
- back_end, is_hp, bus, model, serial, dev_file, host, port = \
- parseDeviceURI(p.device_uri)
-
- except Error:
- continue
-
- if back_end_filter == '*' or back_end in back_end_filter:
- try:
- devices[p.device_uri]
- except KeyError:
- devices[p.device_uri] = [p.name]
- else:
- devices[p.device_uri].append(p.name)
-
- return devices # { 'device_uri' : [ CUPS printer list ], ... }
-
-
- def parseDeviceID(device_id):
- d= {}
- x = [y.strip() for y in device_id.strip().split(';') if y]
-
- for z in x:
- y = z.split(':')
- try:
- d.setdefault(y[0].strip(), y[1])
- except IndexError:
- d.setdefault(y[0].strip(), None)
-
- d.setdefault('MDL', '')
- d.setdefault('SN', '')
-
- if 'MODEL' in d:
- d['MDL'] = d['MODEL']
- del d['MODEL']
-
- if 'SERIAL' in d:
- d['SN'] = d['SERIAL']
- del d['SERIAL']
-
- elif 'SERN' in d:
- d['SN'] = d['SERN']
- del d['SERN']
-
- if d['SN'].startswith('X'):
- d['SN'] = ''
-
- return d
-
-
- def parseDynamicCounter(ctr_field, convert_to_int=True):
- counter, value = ctr_field.split(' ')
- try:
- counter = int(utils.xlstrip(str(counter), '0') or '0')
-
- if convert_to_int:
- value = int(utils.xlstrip(str(value), '0') or '0')
- except ValueError:
- if convert_to_int:
- counter, value = 0, 0
- else:
- counter, value = 0, ''
-
- return counter, value
-
-
- def parseDeviceURI(device_uri):
- #print repr(pat_deviceuri)
- #print repr(device_uri)
- m = pat_deviceuri.match(device_uri)
-
- if m is None:
- log.debug("Device URI %s is invalid/unknown" % device_uri)
- raise Error(ERROR_INVALID_DEVICE_URI)
-
- back_end = m.group(1).lower() or ''
- is_hp = (back_end in ('hp', 'hpfax', 'hpaio'))
- bus = m.group(2).lower() or ''
-
- if bus not in ('usb', 'net', 'bt', 'fw', 'par'):
- log.debug("Device URI %s is invalid/unknown" % device_uri)
- raise Error(ERROR_INVALID_DEVICE_URI)
-
- model = m.group(3) or ''
- serial = m.group(4) or ''
- dev_file = m.group(5) or ''
- host = m.group(6) or ''
- port = m.group(7) or 1
-
- if bus == 'net':
- try:
- port = int(port)
- except (ValueError, TypeError):
- port = 1
-
- if port == 0:
- port = 1
-
- return back_end, is_hp, bus, model, serial, dev_file, host, port
-
-
- def validateBusList(bus, allow_cups=True):
- for b in bus:
- if allow_cups:
- vb = VALID_BUSES
- else:
- vb = VALID_BUSES_WO_CUPS
-
- if b not in vb:
- log.error("Invalid bus name: %s" %b)
- return False
-
- return True
-
-
- def validateFilterList(filter):
- if filter is None:
- return True
-
- for f in filter:
- if f not in VALID_FILTERS:
- log.error("Invalid term '%s' in filter list" % f)
- return False
-
- return True
-
-
- inter_pat = re.compile(r"""%(.*)%""", re.IGNORECASE)
- st = StringTable()
- strings_init = False
-
-
- def initStrings():
- global strings_init, st
- strings_init = True
- cycles = 0
-
- while True:
- found = False
-
- for s in st.string_table:
- short_string, long_string = st.string_table[s]
- short_replace, long_replace = short_string, long_string
-
- try:
- short_match = inter_pat.match(short_string).group(1)
- except (AttributeError, TypeError):
- short_match = None
-
- if short_match is not None:
- found = True
-
- try:
- short_replace, dummy = st.string_table[short_match]
- except KeyError:
- log.error("String interpolation error: %s" % short_match)
-
- try:
- long_match = inter_pat.match(long_string).group(1)
- except (AttributeError, TypeError):
- long_match = None
-
- if long_match is not None:
- found = True
-
- try:
- dummy, long_replace = st.string_table[long_match]
- except KeyError:
- log.error("String interpolation error: %s" % long_match)
-
- if found:
- st.string_table[s] = (short_replace, long_replace)
-
- if not found:
- break
- else:
- cycles +=1
- if cycles > 1000:
- break
-
-
- def queryString(string_id, typ=0):
- if not strings_init:
- initStrings()
-
- #log.debug("queryString(%s)" % string_id)
- s = st.string_table.get(str(string_id), ('', ''))[typ]
-
- if type(s) == type(''):
- return s
-
- return s()
-
-
- AGENT_types = { AGENT_TYPE_NONE : 'invalid',
- AGENT_TYPE_BLACK : 'black',
- AGENT_TYPE_CMY : 'cmy',
- AGENT_TYPE_KCM : 'kcm',
- AGENT_TYPE_CYAN : 'cyan',
- AGENT_TYPE_MAGENTA : 'magenta',
- AGENT_TYPE_YELLOW : 'yellow',
- AGENT_TYPE_CYAN_LOW : 'photo_cyan',
- AGENT_TYPE_MAGENTA_LOW : 'photo_magenta',
- AGENT_TYPE_YELLOW_LOW : 'photo_yellow',
- AGENT_TYPE_GGK : 'photo_gray',
- AGENT_TYPE_BLUE : 'photo_blue',
- AGENT_TYPE_KCMY_CM : 'kcmy_cm',
- AGENT_TYPE_LC_LM : 'photo_cyan_and_photo_magenta',
- #AGENT_TYPE_Y_M : 'yellow_and_magenta',
- #AGENT_TYPE_C_K : 'cyan_and_black',
- AGENT_TYPE_LG_PK : 'light_gray_and_photo_black',
- AGENT_TYPE_LG : 'light_gray',
- AGENT_TYPE_G : 'medium_gray',
- AGENT_TYPE_PG : 'photo_gray',
- AGENT_TYPE_C_M : 'cyan_and_magenta',
- AGENT_TYPE_K_Y : 'black_and_yellow',
- AGENT_TYPE_UNSPECIFIED : 'unspecified', # Kind=5,6
- }
-
- AGENT_kinds = {AGENT_KIND_NONE : 'invalid',
- AGENT_KIND_HEAD : 'head',
- AGENT_KIND_SUPPLY : 'supply',
- AGENT_KIND_HEAD_AND_SUPPLY : 'cartridge',
- AGENT_KIND_TONER_CARTRIDGE : 'toner',
- AGENT_KIND_MAINT_KIT : 'maint_kit', # fuser
- AGENT_KIND_ADF_KIT : 'adf_kit',
- AGENT_KIND_DRUM_KIT : 'drum_kit',
- AGENT_KIND_TRANSFER_KIT : 'transfer_kit',
- AGENT_KIND_INT_BATTERY : 'battery',
- AGENT_KIND_UNKNOWN : 'unknown',
- }
-
- AGENT_healths = {AGENT_HEALTH_OK : 'ok',
- AGENT_HEALTH_MISINSTALLED : 'misinstalled', # supply/cart
- #AGENT_HEALTH_FAIR_MODERATE : '',
- AGENT_HEALTH_INCORRECT : 'incorrect',
- AGENT_HEALTH_FAILED : 'failed',
- AGENT_HEALTH_OVERTEMP : 'overtemp', # battery
- AGENT_HEALTH_CHARGING : 'charging', # battery
- AGENT_HEALTH_DISCHARGING : 'discharging', # battery
- }
-
-
- AGENT_levels = {AGENT_LEVEL_TRIGGER_MAY_BE_LOW : 'low',
- AGENT_LEVEL_TRIGGER_PROBABLY_OUT : 'low',
- AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT : 'out',
- }
-
-
- ##MODEL_UI_REPLACEMENTS = {'laserjet' : 'LaserJet',
- ## 'psc' : 'PSC',
- ## 'officejet' : 'Officejet',
- ## 'deskjet' : 'Deskjet',
- ## 'hp' : 'HP',
- ## 'business' : 'Business',
- ## 'inkjet' : 'Inkjet',
- ## 'photosmart' : 'Photosmart',
- ## 'color' : 'Color',
- ## 'series' : 'series',
- ## 'printer' : 'Printer',
- ## 'mfp' : 'MFP',
- ## 'mopier' : 'Mopier',
- ## 'pro' : 'Pro',
- ## }
-
-
- ##def normalizeModelUIName(model):
- ## if not model.lower().startswith('hp'):
- ## z = 'HP ' + model.replace('_', ' ')
- ## else:
- ## z = model.replace('_', ' ')
- ##
- ## y = []
- ## for x in z.split():
- ## xx = x.lower()
- ## y.append(models.MODEL_UI_REPLACEMENTS.get(xx, xx))
- ##
- ## return ' '.join(y)
-
- ##def normalizeModelName(model):
- ## return utils.xstrip(model.replace(' ', '_').replace('__', '_').replace('~','').replace('/', '_'), '_')
-
-
- def isLocal(bus):
- return bus in ('par', 'usb', 'fw', 'bt')
-
-
- # **************************************************************************** #
-
- string_cache = {}
-
- class Device(object):
- def __init__(self, device_uri, printer_name=None,
- service=None, callback=None, disable_dbus=False):
-
- log.debug("Device URI: %s" % device_uri)
- log.debug("Printer: %s" % printer_name)
-
- global dbus_disabled
- dbus_disabled = disable_dbus
-
- if not disable_dbus:
- if service is None:
- self.dbus_avail, self.service = init_dbus()
- else:
- self.dbus_avail = True
- self.service = service
- else:
- self.dbus_avail = False
- self.service = None
-
- self.last_event = None # Used in devmgr if dbus is disabled
-
- printers = cups.getPrinters()
-
- if device_uri is None and printer_name is not None:
- for p in printers:
- if p.name.lower() == printer_name.lower():
- device_uri = p.device_uri
- break
- else:
- raise Error(ERROR_DEVICE_NOT_FOUND)
-
- self.device_uri = device_uri
- self.callback = callback
- self.device_type = DEVICE_TYPE_UNKNOWN
-
- if self.device_uri.startswith('hp:'):
- self.device_type = DEVICE_TYPE_PRINTER
-
- elif self.device_uri.startswith('hpaio:'):
- self.device_type = DEVICE_TYPE_SCANNER
-
- elif self.device_uri.startswith('hpfax:'):
- self.device_type = DEVICE_TYPE_FAX
-
- try:
- self.back_end, self.is_hp, self.bus, self.model, \
- self.serial, self.dev_file, self.host, self.port = \
- parseDeviceURI(self.device_uri)
- except Error:
- self.io_state = IO_STATE_NON_HP
- raise Error(ERROR_INVALID_DEVICE_URI)
-
- log.debug("URI: backend=%s, is_hp=%s, bus=%s, model=%s, serial=%s, dev=%s, host=%s, port=%d" % \
- (self.back_end, self.is_hp, self.bus, self.model, self.serial, self.dev_file, self.host, self.port))
-
- self.model_ui = models.normalizeModelUIName(self.model)
- self.model = models.normalizeModelName(self.model)
-
- log.debug("Model/UI model: %s/%s" % (self.model, self.model_ui))
-
- # TODO:
- #service.setAlertsEx(self.hpssd_sock)
-
- self.mq = {} # Model query
- self.dq = {} # Device query
- self.icon = "default_printer"
- self.cups_printers = []
- self.channels = {} # { 'SERVICENAME' : channel_id, ... }
- self.device_id = -1
- self.r_values = None # ( r_value, r_value_str, rg, rr )
- self.deviceID = ''
- self.panel_check = True
- self.io_state = IO_STATE_HP_READY
- self.is_local = isLocal(self.bus)
-
- self.supported = False
-
- self.queryModel()
- if not self.supported:
- log.error("Unsupported model: %s" % self.model)
- self.sendEvent(STATUS_DEVICE_UNSUPPORTED)
- else:
- self.supported = True
-
-
- self.mq.update({'model' : self.model,
- 'model-ui' : self.model_ui})
-
- self.error_state = ERROR_STATE_ERROR
- self.device_state = DEVICE_STATE_NOT_FOUND
- self.status_code = EVENT_ERROR_DEVICE_NOT_FOUND
-
- for p in printers:
- if self.device_uri == p.device_uri:
- self.cups_printers.append(p.name)
- self.state = p.state # ?
-
- if self.io_state == IO_STATE_NON_HP:
- self.model = p.makemodel.split(',')[0]
-
- try:
- self.first_cups_printer = self.cups_printers[0]
- except IndexError:
- self.first_cups_printer = ''
-
- if self.mq.get('fax-type', FAX_TYPE_NONE) != FAX_TYPE_NONE:
- self.dq.update({ 'fax-uri' : self.device_uri.replace('hp:/', 'hpfax:/').replace('hpaio:/', 'hpfax:/')})
-
- if self.mq.get('scan-type', SCAN_TYPE_NONE) != SCAN_TYPE_NONE:
- self.dq.update({ 'scan-uri' : self.device_uri.replace('hp:/', 'hpaio:/').replace('hpfax:/', 'hpaio:/')})
-
- self.dq.update({
- 'back-end' : self.back_end,
- 'is-hp' : self.is_hp,
- 'serial' : self.serial,
- 'dev-file' : self.dev_file,
- 'host' : self.host,
- 'port' : self.port,
- 'cups-printer' : ','.join(self.cups_printers),
- 'status-code' : self.status_code,
- 'status-desc' : '',
- 'deviceid' : '',
- 'panel' : 0,
- 'panel-line1' : '',
- 'panel-line2' : '',
- 'device-state' : self.device_state,
- 'error-state' : self.error_state,
- 'device-uri' : self.device_uri,
- 'cups-uri' : self.device_uri.replace('hpfax:/', 'hp:/').replace('hpaio:/', 'hp:/'),
- })
-
- self.device_vars = {
- 'URI' : self.device_uri,
- 'DEVICE_URI' : self.device_uri,
- 'SCAN_URI' : self.device_uri.replace('hp:', 'hpaio:'),
- 'SANE_URI' : self.device_uri.replace('hp:', 'hpaio:'),
- 'FAX_URI' : self.device_uri.replace('hp:', 'hpfax:'),
- 'PRINTER' : self.first_cups_printer,
- 'HOME' : prop.home_dir,
- }
-
-
-
-
- def sendEvent(self, event_code, printer_name='', job_id=0, title=''):
- if self.dbus_avail:
- try:
- self.service.SendEvent(self.device_uri, printer_name, event_code, prop.username, job_id, title)
- except dbus.exceptions.DBusException, e:
- log.debug("dbus call to SendEvent() failed.")
-
-
- def quit(self):
- pass
-
-
- def queryModel(self):
- if not self.mq:
- self.mq = queryModelByURI(self.device_uri)
-
- self.supported = bool(self.mq)
-
- if self.supported:
- for m in self.mq:
- self.__dict__[m.replace('-','_')] = self.mq[m]
-
-
- def queryString(self, string_id):
- return queryString(string_id)
-
-
- def open(self, open_for_printing=False):
- if self.supported and self.io_state in (IO_STATE_HP_READY, IO_STATE_HP_NOT_AVAIL):
- prev_device_state = self.device_state
- self.io_state = IO_STATE_HP_NOT_AVAIL
- self.device_state = DEVICE_STATE_NOT_FOUND
- self.error_state = ERROR_STATE_ERROR
- self.status_code = EVENT_ERROR_DEVICE_NOT_FOUND
- self.device_id = -1
- self.open_for_printing = open_for_printing
-
- if open_for_printing:
- log.debug("Opening device: %s (for printing)" % self.device_uri)
- self.io_mode = self.mq.get('io-mode', hpmudext.HPMUD_UNI_MODE)
- else:
- log.debug("Opening device: %s (not for printing)" % self.device_uri)
- self.io_mode = self.mq.get('io-mfp-mode', hpmudext.HPMUD_UNI_MODE)
-
- log.debug("I/O mode=%d" % self.io_mode)
- result_code, self.device_id = \
- hpmudext.open_device(self.device_uri, self.io_mode)
-
- if result_code != hpmudext.HPMUD_R_OK:
- self.error_state = ERROR_STATE_ERROR
- self.sendEvent(result_code+ERROR_CODE_BASE)
-
- if result_code == hpmudext.HPMUD_R_DEVICE_BUSY:
- log.error("Device busy: %s" % self.device_uri)
- else:
- log.error("Unable to communicate with device (code=%d): %s" % (result_code, self.device_uri))
-
- self.last_event = Event(self.device_uri, '', EVENT_ERROR_DEVICE_NOT_FOUND,
- prop.username, 0, '', time.time())
-
- raise Error(ERROR_DEVICE_NOT_FOUND)
-
- else:
- log.debug("device-id=%d" % self.device_id)
- self.io_state = IO_STATE_HP_OPEN
- self.error_state = ERROR_STATE_CLEAR
- log.debug("Opened device: %s (backend=%s, is_hp=%s, bus=%s, model=%s, dev=%s, serial=%s, host=%s, port=%d)" %
- (self.back_end, self.device_uri, self.is_hp, self.bus, self.model,
- self.dev_file, self.serial, self.host, self.port))
-
- if prev_device_state == DEVICE_STATE_NOT_FOUND:
- self.device_state = DEVICE_STATE_JUST_FOUND
- else:
- self.device_state = DEVICE_STATE_FOUND
-
- self.getDeviceID()
- self.getSerialNumber()
- return self.device_id
-
-
-
- def close(self):
- if self.io_state == IO_STATE_HP_OPEN:
- log.debug("Closing device...")
-
- if len(self.channels) > 0:
-
- for c in self.channels.keys():
- self.__closeChannel(c)
-
- result_code = hpmudext.close_device(self.device_id)
- log.debug("Result-code = %d" % result_code)
-
- self.channels.clear()
- self.io_state = IO_STATE_HP_READY
-
-
- def __openChannel(self, service_name):
- if self.io_state == IO_STATE_HP_OPEN:
- if service_name == hpmudext.HPMUD_S_PRINT_CHANNEL and not self.open_for_printing:
- self.close()
- self.open(True)
- elif service_name != hpmudext.HPMUD_S_PRINT_CHANNEL and self.open_for_printing:
- self.close()
- self.open(False)
- else:
- self.open(service_name == hpmudext.HPMUD_S_PRINT_CHANNEL)
-
- #if not self.mq['io-mode'] == IO_MODE_UNI:
- if 1:
- service_name = service_name.upper()
-
- if service_name not in self.channels:
- log.debug("Opening %s channel..." % service_name)
-
- result_code, channel_id = hpmudext.open_channel(self.device_id, service_name)
-
- self.channels[service_name] = channel_id
- log.debug("channel-id=%d" % channel_id)
- return channel_id
- else:
- return self.channels[service_name]
- else:
- return -1
-
-
- def openChannel(self, service_name):
- return self.__openChannel(service_name)
-
- def openPrint(self):
- return self.__openChannel(hpmudext.HPMUD_S_PRINT_CHANNEL)
-
- def openFax(self):
- return self.__openChannel(hpmudext.HPMUD_S_FAX_SEND_CHANNEL)
-
- def openPCard(self):
- return self.__openChannel(hpmudext.HPMUD_S_MEMORY_CARD_CHANNEL)
-
- def openEWS(self):
- return self.__openChannel(hpmudext.HPMUD_S_EWS_CHANNEL)
-
- def closePrint(self):
- return self.__closeChannel(hpmudext.HPMUD_S_PRINT_CHANNEL)
-
- def closePCard(self):
- return self.__closeChannel(hpmudext.HPMUD_S_MEMORY_CARD_CHANNEL)
-
- def closeFax(self):
- return self.__closeChannel(hpmudext.HPMUD_S_FAX_SEND_CHANNEL)
-
- def openPML(self):
- return self.__openChannel(hpmudext.HPMUD_S_PML_CHANNEL)
-
- def closePML(self):
- return self.__closeChannel(hpmudext.HPMUD_S_PML_CHANNEL)
-
- def closeEWS(self):
- return self.__closeChannel(hpmudext.HPMUD_S_EWS_CHANNEL)
-
- def openCfgUpload(self):
- return self.__openChannel(hpmudext.HPMUD_S_CONFIG_UPLOAD_CHANNEL)
-
- def closeCfgUpload(self):
- return self.__closeChannel(hpmudext.HPMUD_S_CONFIG_UPLOAD_CHANNEL)
-
- def openCfgDownload(self):
- return self.__openChannel(hpmudext.HPMUD_S_CONFIG_DOWNLOAD_CHANNEL)
-
- def closeCfgDownload(self):
- return self.__closeChannel(hpmudext.HPMUD_S_CONFIG_DOWNLOAD_CHANNEL)
-
- def openSoapFax(self):
- return self.__openChannel(hpmudext.HPMUD_S_SOAP_FAX)
-
- def closeSoapFax(self):
- return self.__closeChannel(hpmudext.HPMUD_S_SOAP_FAX)
-
- def __closeChannel(self, service_name):
- #if not self.mq['io-mode'] == IO_MODE_UNI and \
- if self.io_state == IO_STATE_HP_OPEN:
-
- service_name = service_name.upper()
-
- if service_name in self.channels:
- log.debug("Closing %s channel..." % service_name)
-
- result_code = hpmudext.close_channel(self.device_id,
- self.channels[service_name])
-
- del self.channels[service_name]
-
-
- def closeChannel(self, service_name):
- return self.__closeChannel(service_name)
-
-
- def getDeviceID(self):
- needs_close = False
- if self.io_state != IO_STATE_HP_OPEN:
- self.open()
- needs_close = True
-
- result_code, data = hpmudext.get_device_id(self.device_id)
-
- if result_code != hpmudext.HPMUD_R_OK:
- self.raw_deviceID = ''
- self.deviceID = {}
- else:
- self.raw_deviceID = data
- self.deviceID = parseDeviceID(data)
-
- if needs_close:
- self.close()
-
- return self.deviceID
-
-
- def getSerialNumber(self):
- if self.serial:
- return
-
- try:
- self.serial = self.deviceID['SN']
- except KeyError:
- pass
- else:
- if self.serial:
- return
-
- if self.mq.get('status-type', STATUS_TYPE_NONE) != STATUS_TYPE_NONE: # and \
- #not self.mq.get('io-mode', IO_MODE_UNI) == IO_MODE_UNI:
-
- try:
- try:
- error_code, self.serial = self.getPML(pml.OID_SERIAL_NUMBER)
- except Error:
- self.serial = ''
- finally:
- self.closePML()
-
- if self.serial is None:
- self.serial = ''
-
-
- def getThreeBitStatus(self):
- pass
-
-
- def getStatusFromDeviceID(self):
- self.getDeviceID()
- return status.parseStatus(parseDeviceID(self.raw_deviceID))
-
-
- def __parseRValues(self, r_value):
- r_value_str = str(r_value)
- r_value_str = ''.join(['0'*(9 - len(r_value_str)), r_value_str])
- rg, rr = r_value_str[:3], r_value_str[3:]
- r_value = int(rr)
- self.r_values = r_value, r_value_str, rg, rr
- return r_value, r_value_str, rg, rr
-
-
- def getRValues(self, r_type, status_type, dynamic_counters):
- r_value, r_value_str, rg, rr = 0, '000000000', '000', '000000'
-
- if r_type > 0 and \
- dynamic_counters != STATUS_DYNAMIC_COUNTERS_NONE:
-
- if self.r_values is None:
- if self.dbus_avail:
- try:
- r_value = int(self.service.GetCachedIntValue(self.device_uri, 'r_value'))
- except dbus.exceptions.DBusException, e:
- log.debug("dbus call to GetCachedIntValue() failed.")
- r_value = -1
-
- if r_value != -1:
- log.debug("r_value=%d" % r_value)
- r_value, r_value_str, rg, rr = self.__parseRValues(r_value)
-
- return r_value, r_value_str, rg, rr
-
- if self.r_values is None:
-
- if status_type == STATUS_TYPE_S and \
- self.is_local and \
- dynamic_counters != STATUS_DYNAMIC_COUNTERS_PML_SNMP:
-
- try:
- try:
- r_value = self.getDynamicCounter(140)
-
- if r_value is not None:
- log.debug("r_value=%d" % r_value)
- r_value, r_value_str, rg, rr = self.__parseRValues(r_value)
-
- if self.dbus_avail:
- try:
- self.service.SetCachedIntValue(self.device_uri, 'r_value', r_value)
- except dbus.exceptions.DBusException, e:
- log.debug("dbus call to SetCachedIntValue() failed.")
- else:
- log.error("Error attempting to read r-value (2).")
- r_value = 0
- except Error:
- log.error("Error attempting to read r-value (1).")
- r_value = 0
- finally:
- self.closePrint()
-
-
- elif (status_type == STATUS_TYPE_S and
- dynamic_counters == STATUS_DYNAMIC_COUNTERS_PCL and
- not self.is_local) or \
- dynamic_counters == STATUS_DYNAMIC_COUNTERS_PML_SNMP:
-
- try:
- result_code, r_value = self.getPML(pml.OID_R_SETTING)
-
- if r_value is not None:
- log.debug("r_value=%d" % r_value)
- r_value, r_value_str, rg, rr = self.__parseRValues(r_value)
-
- if self.dbus_avail:
- try:
- self.service.SetCachedIntValue(self.device_uri, 'r_value', r_value)
- except dbus.exceptions.DBusException, e:
- log.debug("dbus call to SetCachedIntValue() failed.")
-
- else:
- r_value = 0
-
- finally:
- self.closePML()
-
- else:
- r_value, r_value_str, rg, rr = self.r_values
-
- return r_value, r_value_str, rg, rr
-
-
- def __queryFax(self, quick=False, reread_cups_printers=False):
- io_mode = self.mq.get('io-mode', IO_MODE_UNI)
- self.status_code = STATUS_PRINTER_IDLE
-
- if io_mode != IO_MODE_UNI:
-
- if self.device_state != DEVICE_STATE_NOT_FOUND:
- if self.tech_type in (TECH_TYPE_MONO_INK, TECH_TYPE_COLOR_INK):
- try:
- self.getDeviceID()
- except Error, e:
- log.error("Error getting device ID.")
- self.last_event = Event(self.device_uri, '', ERROR_DEVICE_IO_ERROR,
- prop.username, 0, '', time.time())
-
- raise Error(ERROR_DEVICE_IO_ERROR)
-
- status_desc = self.queryString(self.status_code)
-
- #print self.status_code
-
- self.dq.update({
- 'serial' : self.serial,
- 'cups-printer' : ','.join(self.cups_printers),
- 'status-code' : self.status_code,
- 'status-desc' : status_desc,
- 'deviceid' : self.raw_deviceID,
- 'panel' : 0,
- 'panel-line1' : '',
- 'panel-line2' : '',
- 'device-state' : self.device_state,
- 'error-state' : self.error_state,
- })
-
-
- log.debug("Fax activity check...")
-
- tx_active, rx_active = status.getFaxStatus(self)
-
- if tx_active:
- self.status_code = STATUS_FAX_TX_ACTIVE
- elif rx_active:
- self.status_code = STATUS_FAX_RX_ACTIVE
-
- #print self.status_code
-
- self.error_state = STATUS_TO_ERROR_STATE_MAP.get(self.status_code, ERROR_STATE_CLEAR)
- self.sendEvent(self.status_code)
-
- #print "Error state=", self.error_state, self.device_uri
-
- try:
- self.dq.update({'status-desc' : self.queryString(self.status_code),
- 'error-state' : self.error_state,
- })
-
- except (KeyError, Error):
- self.dq.update({'status-desc' : '',
- 'error-state' : ERROR_STATE_CLEAR,
- })
-
-
- if self.panel_check:
- self.panel_check = bool(self.mq.get('panel-check-type', 0))
-
- status_type = self.mq.get('status-type', STATUS_TYPE_NONE)
- if self.panel_check and \
- status_type in (STATUS_TYPE_LJ, STATUS_TYPE_S, STATUS_TYPE_VSTATUS) and \
- io_mode != IO_MODE_UNI:
-
- log.debug("Panel check...")
- try:
- self.panel_check, line1, line2 = status.PanelCheck(self)
- finally:
- self.closePML()
-
- self.dq.update({'panel': int(self.panel_check),
- 'panel-line1': line1,
- 'panel-line2': line2,})
-
- if not quick and reread_cups_printers:
- self.cups_printers = []
- log.debug("Re-reading CUPS printer queue information.")
- printers = cups.getPrinters()
- for p in printers:
- if self.device_uri == p.device_uri:
- self.cups_printers.append(p.name)
- self.state = p.state # ?
-
- if self.io_state == IO_STATE_NON_HP:
- self.model = p.makemodel.split(',')[0]
-
- self.dq.update({'cups-printer' : ','.join(self.cups_printers)})
-
- try:
- self.first_cups_printer = self.cups_printers[0]
- except IndexError:
- self.first_cups_printer = ''
-
-
- for d in self.dq:
- self.__dict__[d.replace('-','_')] = self.dq[d]
-
- self.last_event = Event(self.device_uri, '', self.status_code, prop.username, 0, '', time.time())
- #print self.last_event
-
- log.debug(self.dq)
-
- #import pprint
-
- #pprint.pprint(self.dq)
-
-
-
-
- def queryDevice(self, quick=False, reread_cups_printers=False):
- if not self.supported:
- self.dq = {}
-
- self.last_event = Event(self.device_uri, '', STATUS_DEVICE_UNSUPPORTED,
- prop.username, 0, '', time.time())
-
- return
-
- if self.device_type == DEVICE_TYPE_FAX:
- return self.__queryFax(quick, reread_cups_printers)
-
- r_type = self.mq.get('r-type', 0)
- tech_type = self.mq.get('tech-type', TECH_TYPE_NONE)
- status_type = self.mq.get('status-type', STATUS_TYPE_NONE)
- battery_check = self.mq.get('status-battery-check', STATUS_BATTERY_CHECK_NONE)
- dynamic_counters = self.mq.get('status-dynamic-counters', STATUS_DYNAMIC_COUNTERS_NONE)
- io_mode = self.mq.get('io-mode', IO_MODE_UNI)
- io_mfp_mode = self.mq.get('io-mfp-mode', IO_MODE_UNI)
- status_code = STATUS_UNKNOWN
-
- # Turn off status if local connection and bi-di not avail.
- #if io_mode == IO_MODE_UNI and self.back_end != 'net':
- # status_type = STATUS_TYPE_NONE
-
- agents = []
-
- if self.device_state != DEVICE_STATE_NOT_FOUND:
- if self.tech_type in (TECH_TYPE_MONO_INK, TECH_TYPE_COLOR_INK):
- try:
- self.getDeviceID()
- except Error, e:
- log.error("Error getting device ID.")
- self.last_event = Event(self.device_uri, '', ERROR_DEVICE_IO_ERROR,
- prop.username, 0, '', time.time())
-
- raise Error(ERROR_DEVICE_IO_ERROR)
-
- status_desc = self.queryString(self.status_code)
-
- self.dq.update({
- 'serial' : self.serial,
- 'cups-printer' : ','.join(self.cups_printers),
- 'status-code' : self.status_code,
- 'status-desc' : status_desc,
- 'deviceid' : self.raw_deviceID,
- 'panel' : 0,
- 'panel-line1' : '',
- 'panel-line2' : '',
- 'device-state' : self.device_state,
- 'error-state' : self.error_state,
- })
-
- status_block = {}
-
- if status_type == STATUS_TYPE_NONE:
- log.warn("No status available for device.")
- status_block = {'status-code' : STATUS_UNKNOWN}
-
- elif status_type in (STATUS_TYPE_VSTATUS, STATUS_TYPE_S):
- log.debug("Type 1/2 (S: or VSTATUS:) status")
- status_block = status.parseStatus(self.deviceID)
-
- elif status_type in (STATUS_TYPE_LJ, STATUS_TYPE_PML_AND_PJL):
- log.debug("Type 3/9 LaserJet PML(+PJL) status")
- status_block = status.StatusType3(self, self.deviceID)
-
- elif status_type == STATUS_TYPE_LJ_XML:
- log.debug("Type 6: LJ XML")
- status_block = status.StatusType6(self)
-
- elif status_type == STATUS_TYPE_PJL:
- log.debug("Type 8: LJ PJL")
- status_block = status.StatusType8(self)
-
- else:
- log.error("Unimplemented status type: %d" % status_type)
-
- if battery_check and \
- io_mode != IO_MODE_UNI:
-
- log.debug("Battery check...")
- status.BatteryCheck(self, status_block, battery_check)
-
- if status_block:
- log.debug(status_block)
- self.dq.update(status_block)
- try:
- status_block['agents']
- except KeyError:
- pass
- else:
- agents = status_block['agents']
- del self.dq['agents']
-
-
- status_code = self.dq.get('status-code', STATUS_UNKNOWN)
-
- ## if not quick and \
- ## self.mq.get('fax-type', FAX_TYPE_NONE) and \
- ## status_code == STATUS_PRINTER_IDLE and \
- ## io_mode != IO_MODE_UNI:
- ##
- ## log.debug("Fax activity check...")
- ##
- ## tx_active, rx_active = status.getFaxStatus(self)
- ##
- ## if tx_active:
- ## status_code = STATUS_FAX_TX_ACTIVE
- ## elif rx_active:
- ## status_code = STATUS_FAX_RX_ACTIVE
-
-
- self.error_state = STATUS_TO_ERROR_STATE_MAP.get(status_code, ERROR_STATE_CLEAR)
- self.sendEvent(status_code)
-
- #print "Error state=", self.error_state, self.device_uri
-
- try:
- self.dq.update({'status-desc' : self.queryString(status_code),
- 'error-state' : self.error_state,
- })
-
- except (KeyError, Error):
- self.dq.update({'status-desc' : '',
- 'error-state' : ERROR_STATE_CLEAR,
- })
-
- r_value = 0
-
- if not quick and status_type != STATUS_TYPE_NONE:
- if self.panel_check:
- self.panel_check = bool(self.mq.get('panel-check-type', 0))
-
- if self.panel_check and \
- status_type in (STATUS_TYPE_LJ, STATUS_TYPE_S, STATUS_TYPE_VSTATUS) and \
- io_mode != IO_MODE_UNI:
-
- log.debug("Panel check...")
- try:
- self.panel_check, line1, line2 = status.PanelCheck(self)
- finally:
- self.closePML()
-
- self.dq.update({'panel': int(self.panel_check),
- 'panel-line1': line1,
- 'panel-line2': line2,})
-
-
- if dynamic_counters != STATUS_DYNAMIC_COUNTERS_NONE and \
- io_mode != IO_MODE_UNI:
-
- r_value, r_value_str, rg, rr = self.getRValues(r_type, status_type, dynamic_counters)
- else:
- r_value, r_value_str, rg, rr = 0, '000000000', '000', '000000'
-
- self.dq.update({'r' : r_value,
- 'rs' : r_value_str,
- 'rg' : rg,
- 'rr' : rr,
- })
-
- if not quick and reread_cups_printers:
- self.cups_printers = []
- log.debug("Re-reading CUPS printer queue information.")
- printers = cups.getPrinters()
- for p in printers:
- if self.device_uri == p.device_uri:
- self.cups_printers.append(p.name)
- self.state = p.state # ?
-
- if self.io_state == IO_STATE_NON_HP:
- self.model = p.makemodel.split(',')[0]
-
- self.dq.update({'cups-printer' : ','.join(self.cups_printers)})
-
- try:
- self.first_cups_printer = self.cups_printers[0]
- except IndexError:
- self.first_cups_printer = ''
-
- if not quick:
- # Make sure there is some valid agent data for this r_value
- # If not, fall back to r_value == 0
- if r_value > 0 and self.mq.get('r%d-agent1-kind' % r_value, 0) == 0:
- r_value = 0
- self.dq.update({'r' : r_value,
- 'rs' : r_value_str,
- 'rg' : rg,
- 'rr' : rr,
- })
-
- a, aa = 1, 1
- while True:
- mq_agent_kind = self.mq.get('r%d-agent%d-kind' % (r_value, a), -1)
-
- if mq_agent_kind == -1:
- break
-
- mq_agent_type = self.mq.get('r%d-agent%d-type' % (r_value, a), 0)
- mq_agent_sku = self.mq.get('r%d-agent%d-sku' % (r_value, a), '')
-
- found = False
-
- log.debug("Looking for kind=%d, type=%d..." % (mq_agent_kind, mq_agent_type))
- for agent in agents:
- agent_kind = agent['kind']
- agent_type = agent['type']
-
- if agent_kind == mq_agent_kind and \
- agent_type == mq_agent_type:
- found = True
- break
-
- if found:
- log.debug("found: r%d-kind%d-type%d" % (r_value, agent_kind, agent_type))
-
- agent_health = agent.get('health', AGENT_HEALTH_OK)
- agent_level = agent.get('level', 100)
- agent_level_trigger = agent.get('level-trigger',
- AGENT_LEVEL_TRIGGER_SUFFICIENT_0)
-
- log.debug("health=%d, level=%d, level_trigger=%d, status_code=%d" %
- (agent_health, agent_level, agent_level_trigger, status_code))
-
- query = 'agent_%s_%s' % (AGENT_types.get(agent_type, 'unknown'),
- AGENT_kinds.get(agent_kind, 'unknown'))
-
- agent_desc = self.queryString(query)
- query = 'agent_health_ok'
-
- # If printer is not in an error state, and
- # if agent health is OK, check for low supplies. If low, use
- # the agent level trigger description for the agent description.
- # Otherwise, report the agent health.
- if (status_code == STATUS_PRINTER_IDLE or status_code == STATUS_PRINTER_OUT_OF_INK) and \
- (agent_health == AGENT_HEALTH_OK or
- (agent_health == AGENT_HEALTH_FAIR_MODERATE and agent_kind == AGENT_KIND_HEAD)) and \
- agent_level_trigger >= AGENT_LEVEL_TRIGGER_MAY_BE_LOW:
-
- query = 'agent_level_%s' % AGENT_levels.get(agent_level_trigger, 'unknown')
-
- if tech_type in (TECH_TYPE_MONO_INK, TECH_TYPE_COLOR_INK):
- code = agent_type + STATUS_PRINTER_LOW_INK_BASE
- else:
- code = agent_type + STATUS_PRINTER_LOW_TONER_BASE
-
- self.dq['status-code'] = code
- self.dq['status-desc'] = self.queryString(code)
-
- self.dq['error-state'] = STATUS_TO_ERROR_STATE_MAP.get(code, ERROR_STATE_LOW_SUPPLIES)
- self.sendEvent(code)
-
- if agent_level_trigger in \
- (AGENT_LEVEL_TRIGGER_PROBABLY_OUT, AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT):
-
- query = 'agent_level_out'
- else:
- query = 'agent_level_low'
-
- agent_health_desc = self.queryString(query)
-
- self.dq.update(
- {
- 'agent%d-kind' % aa : agent_kind,
- 'agent%d-type' % aa : agent_type,
- 'agent%d-known' % aa : agent.get('known', False),
- 'agent%d-sku' % aa : mq_agent_sku,
- 'agent%d-level' % aa : agent_level,
- 'agent%d-level-trigger' % aa : agent_level_trigger,
- 'agent%d-ack' % aa : agent.get('ack', False),
- 'agent%d-hp-ink' % aa : agent.get('hp-ink', False),
- 'agent%d-health' % aa : agent_health,
- 'agent%d-dvc' % aa : agent.get('dvc', 0),
- 'agent%d-virgin' % aa : agent.get('virgin', False),
- 'agent%d-desc' % aa : agent_desc,
- 'agent%d-id' % aa : agent.get('id', 0),
- 'agent%d-health-desc' % aa : agent_health_desc,
- })
-
- else:
- query = 'agent_health_%s' % AGENT_healths.get(agent_health, AGENT_HEALTH_OK)
- agent_health_desc = self.queryString(query)
-
- self.dq.update(
- {
- 'agent%d-kind' % aa : agent_kind,
- 'agent%d-type' % aa : agent_type,
- 'agent%d-known' % aa : False,
- 'agent%d-sku' % aa : mq_agent_sku,
- 'agent%d-level' % aa : agent_level,
- 'agent%d-level-trigger' % aa : agent_level_trigger,
- 'agent%d-ack' % aa : False,
- 'agent%d-hp-ink' % aa : False,
- 'agent%d-health' % aa : agent_health,
- 'agent%d-dvc' % aa : 0,
- 'agent%d-virgin' % aa : False,
- 'agent%d-desc' % aa : agent_desc,
- 'agent%d-id' % aa : 0,
- 'agent%d-health-desc' % aa : agent_health_desc,
- })
-
- aa += 1
-
- else:
- log.debug("Not found: %d" % a)
-
- a += 1
-
- else: # Create agent keys for not-found devices
-
- r_value = 0
- if r_type > 0 and self.r_values is not None:
- r_value = self.r_values[0]
-
- # Make sure there is some valid agent data for this r_value
- # If not, fall back to r_value == 0
- if r_value > 0 and self.mq.get('r%d-agent1-kind', 0) == 0:
- r_value = 0
-
- a = 1
- while True:
- mq_agent_kind = self.mq.get('r%d-agent%d-kind' % (r_value, a), 0)
-
- if mq_agent_kind == 0:
- break
-
- mq_agent_type = self.mq.get('r%d-agent%d-type' % (r_value, a), 0)
- mq_agent_sku = self.mq.get('r%d-agent%d-sku' % (r_value, a), '')
- query = 'agent_%s_%s' % (AGENT_types.get(mq_agent_type, 'unknown'),
- AGENT_kinds.get(mq_agent_kind, 'unknown'))
-
- agent_desc = self.queryString(query)
-
- self.dq.update(
- {
- 'agent%d-kind' % a : mq_agent_kind,
- 'agent%d-type' % a : mq_agent_type,
- 'agent%d-known' % a : False,
- 'agent%d-sku' % a : mq_agent_sku,
- 'agent%d-level' % a : 0,
- 'agent%d-level-trigger' % a : AGENT_LEVEL_TRIGGER_ALMOST_DEFINITELY_OUT,
- 'agent%d-ack' % a : False,
- 'agent%d-hp-ink' % a : False,
- 'agent%d-health' % a : AGENT_HEALTH_MISINSTALLED,
- 'agent%d-dvc' % a : 0,
- 'agent%d-virgin' % a : False,
- 'agent%d-health-desc' % a : self.queryString('agent_health_unknown'),
- 'agent%d-desc' % a : agent_desc,
- 'agent%d-id' % a : 0,
- })
-
- a += 1
-
- for d in self.dq:
- self.__dict__[d.replace('-','_')] = self.dq[d]
-
- self.last_event = Event(self.device_uri, '', status_code, prop.username, 0, '', time.time())
- log.debug(self.dq)
-
-
- def isBusyOrInErrorState(self):
- self.queryDevice(quick=True)
- return self.error_state > ERROR_STATE_MAX_OK
-
- def isIdleAndNoError(self):
- self.queryDevice(quick=True)
- #print self.error_state
- return self.error_state <= ERROR_STATE_MAX_OK
-
- def getPML(self, oid, desired_int_size=pml.INT_SIZE_INT): # oid => ( 'dotted oid value', pml type )
- channel_id = self.openPML()
-
- result_code, data, typ, pml_result_code = \
- hpmudext.get_pml(self.device_id, channel_id, pml.PMLToSNMP(oid[0]), oid[1])
-
- if pml_result_code > pml.ERROR_MAX_OK:
- log.debug("PML/SNMP GET %s failed (result code = 0x%x)" % (oid[0], pml_result_code))
- return pml_result_code, None
-
- converted_data = pml.ConvertFromPMLDataFormat(data, oid[1], desired_int_size)
-
- if log.is_debug():
- if oid[1] in (pml.TYPE_STRING, pml.TYPE_BINARY):
-
- log.debug("PML/SNMP GET %s (result code = 0x%x) returned:" %
- (oid[0], pml_result_code))
- log.log_data(data)
- else:
- log.debug("PML/SNMP GET %s (result code = 0x%x) returned: %s" %
- (oid[0], pml_result_code, repr(converted_data)))
-
- return pml_result_code, converted_data
-
-
- def setPML(self, oid, value): # oid => ( 'dotted oid value', pml type )
- channel_id = self.openPML()
-
- value = pml.ConvertToPMLDataFormat(value, oid[1])
-
- result_code, pml_result_code = \
- hpmudext.set_pml(self.device_id, channel_id, pml.PMLToSNMP(oid[0]), oid[1], value)
-
- if log.is_debug():
- if oid[1] in (pml.TYPE_STRING, pml.TYPE_BINARY):
-
- log.debug("PML/SNMP SET %s (result code = 0x%x) to:" %
- (oid[0], pml_result_code))
- log.log_data(value)
- else:
- log.debug("PML/SNMP SET %s (result code = 0x%x) to: %s" %
- (oid[0], pml_result_code, repr(value)))
-
- return pml_result_code
-
-
- def getDynamicCounter(self, counter, convert_to_int=True):
- dynamic_counters = self.mq.get('status-dynamic-counters', STATUS_DYNAMIC_COUNTERS_NONE)
- log.debug("Dynamic counters: %d" % dynamic_counters)
- if dynamic_counters != STATUS_DYNAMIC_COUNTERS_NONE:
-
- if dynamic_counters == STATUS_DYNAMIC_COUNTERS_LIDIL_0_5_4:
- self.printData(ldl.buildResetPacket(), direct=True)
- self.printData(ldl.buildDynamicCountersPacket(counter), direct=True)
- else:
- self.printData(pcl.buildDynamicCounter(counter), direct=True)
-
- value, tries, times_seen, sleepy_time, max_tries = 0, 0, 0, 0.1, 5
- time.sleep(0.1)
-
- while True:
-
- if self.callback:
- self.callback()
-
- sleepy_time += 0.1
- tries += 1
-
- time.sleep(sleepy_time)
-
- self.getDeviceID()
-
- if 'CTR' in self.deviceID and \
- pat_dynamic_ctr.search(self.raw_deviceID) is not None:
- dev_counter, value = parseDynamicCounter(self.deviceID['CTR'], convert_to_int)
-
- if counter == dev_counter:
- self.printData(pcl.buildDynamicCounter(0), direct=True)
- # protect the value as a string during msg handling
- if not convert_to_int:
- value = '#' + value
- return value
-
- if tries > max_tries:
- if dynamic_counters == STATUS_DYNAMIC_COUNTERS_LIDIL_0_5_4:
- self.printData(ldl.buildResetPacket())
- self.printData(ldl.buildDynamicCountersPacket(counter), direct=True)
- else:
- self.printData(pcl.buildDynamicCounter(0), direct=True)
-
- return None
-
- if dynamic_counters == STATUS_DYNAMIC_COUNTERS_LIDIL_0_5_4:
- self.printData(ldl.buildResetPacket())
- self.printData(ldl.buildDynamicCountersPacket(counter), direct=True)
- else:
- self.printData(pcl.buildDynamicCounter(counter), direct=True)
-
- else:
- raise Error(ERROR_DEVICE_DOES_NOT_SUPPORT_OPERATION)
-
-
- def readPrint(self, bytes_to_read, stream=None, timeout=prop.read_timeout, allow_short_read=False):
- return self.__readChannel(self.openPrint, bytes_to_read, stream, timeout, allow_short_read)
-
- def readPCard(self, bytes_to_read, stream=None, timeout=prop.read_timeout, allow_short_read=False):
- return self.__readChannel(self.openPCard, bytes_to_read, stream, timeout, allow_short_read)
-
- def readFax(self, bytes_to_read, stream=None, timeout=prop.read_timeout, allow_short_read=False):
- return self.__readChannel(self.openFax, bytes_to_read, stream, timeout, allow_short_read)
-
- def readCfgUpload(self, bytes_to_read, stream=None, timeout=prop.read_timeout, allow_short_read=False):
- return self.__readChannel(self.openCfgUpload, bytes_to_read, stream, timeout, allow_short_read)
-
- def readEWS(self, bytes_to_read, stream=None, timeout=prop.read_timeout, allow_short_read=True):
- return self.__readChannel(self.openEWS, bytes_to_read, stream, timeout, allow_short_read)
-
- def readSoapFax(self, bytes_to_read, stream=None, timeout=prop.read_timeout, allow_short_read=True):
- return self.__readChannel(self.openSoapFax, bytes_to_read, stream, timeout, allow_short_read)
-
- def __readChannel(self, opener, bytes_to_read, stream=None,
- timeout=prop.read_timeout, allow_short_read=False):
-
- channel_id = opener()
-
- log.debug("Reading channel %d..." % channel_id)
-
- num_bytes = 0
-
- if stream is None:
- buffer = ''
-
- while True:
- result_code, data = \
- hpmudext.read_channel(self.device_id, channel_id, bytes_to_read, timeout)
-
- l = len(data)
-
- if result_code == hpmudext.HPMUD_R_IO_TIMEOUT:
- log.debug("I/O timeout")
- break
-
- if result_code != hpmudext.HPMUD_R_OK:
- log.error("Channel read error")
- raise Error(ERROR_DEVICE_IO_ERROR)
-
- if not l:
- log.debug("End of data")
- break
-
- if stream is None:
- buffer = ''.join([buffer, data])
- else:
- stream.write(data)
-
- num_bytes += l
-
- if self.callback is not None:
- self.callback()
-
- if num_bytes == bytes_to_read:
- log.debug("Full read complete.")
- break
-
- if allow_short_read and num_bytes < bytes_to_read:
- log.debug("Allowed short read of %d of %d bytes complete." % (num_bytes, bytes_to_read))
- break
-
- if stream is None:
- log.debug("Returned %d total bytes in buffer." % num_bytes)
- return buffer
- else:
- log.debug("Saved %d total bytes to stream." % num_bytes)
- return num_bytes
-
-
- def writePrint(self, data):
- return self.__writeChannel(self.openPrint, data)
-
- def writePCard(self, data):
- return self.__writeChannel(self.openPCard, data)
-
- def writeFax(self, data):
- return self.__writeChannel(self.openFax, data)
-
- def writeEWS(self, data):
- return self.__writeChannel(self.openEWS, data)
-
- def writeCfgDownload(self, data):
- return self.__writeChannel(self.openCfgDownload, data)
-
- def writeSoapFax(self, data):
- return self.__writeChannel(self.openSoapFax, data)
-
-
- def __writeChannel(self, opener, data):
- channel_id = opener()
-
- buffer, bytes_out, total_bytes_to_write = data, 0, len(data)
- log.debug("Writing %d bytes to channel %d..." % (total_bytes_to_write,channel_id))
-
- while len(buffer) > 0:
- result_code, bytes_written = \
- hpmudext.write_channel(self.device_id, channel_id,
- buffer[:prop.max_message_len])
-
- if result_code != hpmudext.HPMUD_R_OK:
- log.error("Channel write error")
- raise Error(ERROR_DEVICE_IO_ERROR)
-
- buffer = buffer[prop.max_message_len:]
- bytes_out += bytes_written
-
- if self.callback is not None:
- self.callback()
-
- if total_bytes_to_write != bytes_out:
- raise Error(ERROR_DEVICE_IO_ERROR)
-
- return bytes_out
-
-
- def writeEmbeddedPML(self, oid, value, style=1, direct=True):
- if style == 1:
- func = pcl.buildEmbeddedPML2
- else:
- func = pcl.buildEmbeddedPML
-
- data = func(pcl.buildPCLCmd('&', 'b', 'W',
- pml.buildEmbeddedPMLSetPacket(oid[0],
- value,
- oid[1])))
-
- log.log_data(data)
-
- self.printData(data, direct=direct, raw=True)
-
-
- def printGzipFile(self, file_name, printer_name=None, direct=False, raw=True, remove=False):
- return self.printFile(file_name, printer_name, direct, raw, remove)
-
- def printParsedGzipPostscript(self, print_file, printer_name=None):
- # always: direct=False, raw=False, remove=True
- try:
- os.stat(print_file)
- except OSError:
- log.error("File not found: %s" % print_file)
- return
-
- temp_file_fd, temp_file_name = utils.make_temp_file()
- f = gzip.open(print_file, 'r')
-
- x = f.readline()
- while not x.startswith('%PY_BEGIN'):
- os.write(temp_file_fd, x)
- x = f.readline()
-
- sub_lines = []
- x = f.readline()
- while not x.startswith('%PY_END'):
- sub_lines.append(x)
- x = f.readline()
-
- SUBS = {'VERSION' : prop.version,
- 'MODEL' : self.model_ui,
- 'URI' : self.device_uri,
- 'BUS' : self.bus,
- 'SERIAL' : self.serial,
- 'IP' : self.host,
- 'PORT' : self.port,
- 'DEVNODE' : self.dev_file,
- }
-
- if self.bus == 'net':
- SUBS['DEVNODE'] = 'n/a'
- else:
- SUBS['IP'] = 'n/a'
- SUBS['PORT'] = 'n/a'
-
- for s in sub_lines:
- os.write(temp_file_fd, s % SUBS)
-
- os.write(temp_file_fd, f.read())
- f.close()
- os.close(temp_file_fd)
-
- self.printFile(temp_file_name, printer_name, direct=False, raw=False, remove=True)
-
- def printFile(self, file_name, printer_name=None, direct=False, raw=True, remove=False):
- is_gzip = os.path.splitext(file_name)[-1].lower() == '.gz'
-
- if printer_name is None:
- try:
- printer_name = self.cups_printers[0]
- except IndexError:
- raise Error(ERROR_NO_CUPS_QUEUE_FOUND_FOR_DEVICE)
-
- log.debug("Printing file '%s' to queue '%s' (gzip=%s, direct=%s, raw=%s, remove=%s)" %
- (file_name, printer_name, is_gzip, direct, raw, remove))
-
- if direct: # implies raw==True
- if is_gzip:
- self.writePrint(gzip.open(file_name, 'r').read())
- else:
- self.writePrint(file(file_name, 'r').read())
-
- else:
- if not utils.which('lpr'):
- lp_opt = ''
-
- if raw:
- lp_opt = '-oraw'
-
- if is_gzip:
- c = 'gunzip -c %s | lp -c -d%s %s' % (file_name, printer_name, lp_opt)
- else:
- c = 'lp -c -d%s %s %s' % (printer_name, lp_opt, file_name)
-
- log.debug(c)
- exit_code = os.system(c)
-
- if exit_code != 0:
- log.error("Print command failed with exit code %d!" % exit_code)
-
- if remove:
- os.remove(file_name)
-
- else:
- raw_str, rem_str = '', ''
- if raw: raw_str = '-o raw'
- if remove: rem_str = '-r'
-
- if is_gzip:
- c = 'gunzip -c %s | lpr %s %s -P%s' % (file_name, raw_str, rem_str, printer_name)
- else:
- c = 'lpr -P%s %s %s %s' % (printer_name, raw_str, rem_str, file_name)
-
- log.debug(c)
- exit_code = os.system(c)
-
- if exit_code != 0:
- log.error("Print command failed with exit code %d!" % exit_code)
-
-
- def printTestPage(self, printer_name=None):
- return self.printParsedGzipPostscript(os.path.join( prop.home_dir, 'data',
- 'ps', 'testpage.ps.gz' ), printer_name)
-
-
- def printData(self, data, printer_name=None, direct=True, raw=True):
- #log.log_data(data)
- #log.debug("printData(direct=%s, raw=%s)" % (direct, raw))
- if direct:
- self.writePrint(data)
- else:
- temp_file_fd, temp_file_name = utils.make_temp_file()
- os.write(temp_file_fd, data)
- os.close(temp_file_fd)
-
- self.printFile(temp_file_name, printer_name, False, raw, remove=True)
-
-
- def cancelJob(self, jobid):
- cups.cancelJob(jobid)
- self.sendEvent(STATUS_PRINTER_CANCELING)
-
-
- def queryHistory(self):
- result = []
-
- if self.dbus_avail:
- try:
- history = list(self.service.GetHistory(self.device_uri))
- except dbus.exceptions.DBusException, e:
- log.debug("dbus call to GetHistory() failed.")
- history = []
-
- history.reverse()
-
- for h in history:
- result.append(Event(*tuple(h)))
-
- try:
- self.error_code = result[0].event_code
- except IndexError:
- self.error_code = STATUS_UNKNOWN
-
- self.error_state = STATUS_TO_ERROR_STATE_MAP.get(self.error_code, ERROR_STATE_CLEAR)
-
- else:
- self.error_code = STATUS_UNKNOWN
- self.error_state = ERROR_STATE_CLEAR
-
- self.hist = result
- return result
-
-
-
- def getEWSUrl(self, url, stream):
- try:
- if self.is_local:
- url2 = "%s&loc=%s" % (self.device_uri.replace('hpfax:', 'hp:'), url)
- data = self
- else:
- url2 = "http://%s%s" % (self.host, url)
- data = None
-
- log.debug("Opening: %s" % url2)
- opener = LocalOpener({})
- try:
- f = opener.open(url2, data)
- except Error:
- log.error("Status read failed: %s" % url2)
- stream.seek(0)
- stream.truncate()
- else:
- try:
- stream.write(f.read())
- finally:
- f.close()
-
- finally:
- self.closeEWS()
-
-
- def downloadFirmware(self, usb_bus_id=None, usb_device_id=None):
- ok = False
- filename = os.path.join(prop.data_dir, "firmware", self.model.lower() + '.fw.gz')
- log.debug(filename)
-
- if os.path.exists(filename):
- log.debug("Downloading firmware file '%s'..." % filename)
-
- # Write to port directly (no MUD) so that HAL can enumerate the printer
- if 0: # this currently doesn't work because usblp is loaded...
- #if usb_bus_id is not None and usb_device_id is not None:
- try:
- p = "/dev/bus/usb/%s/%s" % (usb_bus_id, usb_device_id)
- log.debug("Writing to %s..." % p)
- #f = file(p, 'w')
- f = os.open(p, os.O_RDWR)
- x = gzip.open(filename).read()
- os.write(f, x)
- #f.close()
- os.close(f)
- ok = True
- log.debug("OK")
- except (OSError, IOError), e:
- log.error("An error occured: %s" % e)
- else:
- try:
- self.openPrint()
- bytes_written = self.writePrint(gzip.open(filename).read())
- log.debug("%s bytes downloaded." % utils.commafy(bytes_written))
- self.closePrint()
- ok = True
- log.debug("OK")
- except Error, e:
- log.error("An error occured: %s" % e.msg)
- else:
- log.error("Firmware file '%s' not found." % filename)
-
- return ok
-
-
- # ********************************** Support classes/functions
-
-
- class xStringIO(StringIO.StringIO):
- def makefile(self, x, y):
- return self
-
- # URLs: hp:/usb/HP_LaserJet_3050?serial=00XXXXXXXXXX&loc=/hp/device/info_device_status.xml
- class LocalOpener(urllib.URLopener):
- def open_hp(self, url, dev):
- log.debug("open_hp(%s)" % url)
-
- match_obj = http_pat_url.search(url)
- bus = match_obj.group(1) or ''
- model = match_obj.group(2) or ''
- serial = match_obj.group(3) or ''
- device = match_obj.group(4) or ''
- loc = match_obj.group(5) or ''
-
- dev.openEWS()
- dev.writeEWS("""GET %s HTTP/1.0\nContent-Length:0\nHost:localhost\nUser-Agent:hplip\n\n""" % loc)
-
- reply = xStringIO()
-
- while dev.readEWS(8192, reply, timeout=1):
- pass
-
- reply.seek(0)
- log.log_data(reply.getvalue())
-
- response = httplib.HTTPResponse(reply)
- response.begin()
-
- if response.status != httplib.OK:
- raise Error(ERROR_DEVICE_STATUS_NOT_AVAILABLE)
- else:
- return response.fp
-
-
-